You are on page 1of 57

Overview of YouTube APIs

Ask not what our APIs can do for you…

John Harding
July 10, 2008
The Big Idea

All the functionality of YouTube, available on your web site


Watch Videos
Find relevant videos
Manage favorites, playlists, subscriptions, etc.
Upload

YouTube Confidential and Proprietary


Agenda

Google Data API review

YouTube API basics

Overview of YouTube API functionality


Read
Write
Upload

YouTube Confidential and Proprietary


Google Data API Review

Based on Atom Publishing Protocol (APP)


RESTful design
Data represented as Atom, RSS feeds or JSON

Uses standard HTTP


POST to create resources
GET to retrieve resources
PUT to update resources
DELETE to delete resources

YouTube Confidential and Proprietary


YouTube API basics

Different types of feeds (based on content):


Videos
User subscriptions
User playlists
User contacts
Comments
User profile

Most can be read by anyone


Some information may be private

Modifying always requires authentication


YouTube Confidential and Proprietary
Video Feeds

Video feeds represent a set of videos


Search results
Standard feeds
Related videos

User favorites
User uploads
Playlist contents
Video responses

YouTube Confidential and Proprietary


Video Feeds (Atom)
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' …>
<id>http://gdata.youtube.com/…/standardfeeds/most_viewed</id> …
<link rel='next' type='application/atom+xml'
href=‘…viewed?start-index=26&max-results=25&time=all_time'/>
<openSearch:totalResults>100</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry>
<id>http://…/feeds/api/videos/dMH0bHeiRNg</id> …
<title type='text'>Evolution of Dance</title> …
<author><name>judsonlaipply</name>…</author> …
<media:group> … </media:group> …
</entry>
<entry>
<id>http://…/feeds/api/videos/cQ25-glGRzI</id> …
<title type='text'>Avril Lavigne - Girlfriend</title>

</feed>

YouTube Confidential and Proprietary


Video Feeds (Python Client Library)

yt = gdata.youtube.service.YouTubeService()
feed = yt.GetYouTubeVideoFeed(uri)

YouTube Confidential and Proprietary


Video Feeds (English)

A sequence of Video entries, each with:


Title, Description, Author
Category, Keywords
Links to other pages & feeds (Related, Responses, Comments,
etc.)
Thumbnails
Statistics (Ratings, View counts, etc.)
Video players (YouTube watch page, Embedded Player)

YouTube Confidential and Proprietary


Search

YouTube Confidential and Proprietary


Search
/feeds/api/videos/?vq=<search-query>&…

Useful Query Parameters (valid on most feeds):


vq: Search Terms
orderby: “relevance”, “published”, “viewCount”, “rating”
relevance_lang_xx for language-specific relevance
lr: Language restriction
format=5: Only return embeddable videos

Examples:
http://gdata.youtube.com/feeds/api/videos/?vq=lolcats
http://gdata.youtube.com/feeds/api/videos/?vq=skateboarding&orderby=rating
http://gdata.youtube.com/feeds/api/videos/?vq=music+videos&format=5
YouTube Confidential and Proprietary
Standard Feeds

YouTube Confidential and Proprietary


Standard Feeds

/feeds/api/standardfeeds/<feed-name>

Different lists of featured and popular content

Analagous to “Videos” tab on www.youtube.com:


Featured, Most Viewed, Top Rated, etc.
Some offer a variety of time windows (e.g. time=this_week)
All vary by region
Some are broken down by category (e.g. category=Sports)

http://gdata.youtube.com/feeds/api/standardfeeds/recently_featured
http://gdata.youtube.com/feeds/api/standardfeeds/ES/most_viewed
http://gdata.youtube.com/feeds/api/standardfeeds/FR/top_rated?time=today
http://gdata.youtube.com/feeds/api/standardfeeds/top_rated?category=Sports

YouTube Confidential and Proprietary


Related Videos

YouTube Confidential and Proprietary


Related Videos

/feeds/api/videos/<video-id>/related

Returns a list of related videos

YouTube Confidential and Proprietary


Example Time – Standard Feeds and Search

YouTube Confidential and Proprietary


Example Time – Standard Feeds and Search
[util.py]

def MakeGetRequest(self, path, authsub_token=None):


request_headers = {}
if authsub_token:
request_headers.update({'Authorization':
_AuthSubAuthHeader % authsub_token})
request_headers.update(self._GetDeveloperHeaders())
return Fetch(_GDataHost, 'GET', path, request_headers, None)

def _BuildVideoList(dom):
video_entries = dom.getElementsByTagName("entry")
videos_list = []
for video in video_entries:
v = ytvideo.ytvideo()
v.parse_from_xml(video)
videos_list.append(v)
return videos_list

YouTube Confidential and Proprietary


Example Time – Standard Feeds and Search
[home.py]

display_videos = GetStandardFeed(server.MOST_VIEWED,
count=1, time='this_week')
display_videos.extend(GetStandardFeed(server.TOP_RATED,
count=1, time='this_week'))
display_videos.extend(GetStandardFeed(server.FEATURED,
count=1, time=None)

for video in display_videos:


response.write(video_display.video_to_html(video))

_GDataStandardFeedsBasePath = '/feeds/api/standardfeeds'
def GetStandardFeed(self, feed, time='today', count=5):
path = _GDataStandardFeedsBasePath + '/' + feed
if not time is None:
path = path + '?time=' + time
dom = MakeGetRequest(path)
return BuildVideoList(dom)

YouTube Confidential and Proprietary


Example Time – Standard Feeds and Search
[search.py]

query = self.request.get('q')
if query is None:
query = 'YouTube APIs'
videos = GetSearchResults(query, category=None)
response.write(video_display.video_list_to_html(videos))

_GDataVideoSearchPath = '/feeds/api/videos‘
def GetSearchResults(self, query, category=None):
path = _GDataVideoSearchPath
if not category is None:
path = path + '/-/' + urllib.quote(category, safe='')
path = path + '?vq=%s' % urllib.quote(query)
dom = MakeGetRequest(path)
return _BuildVideoList(dom)

YouTube Confidential and Proprietary


Personalization is key

Different ways to personalize the YouTube experience:


Subscriptions
Playlists
Favorites
My uploads
Contacts

YouTube Confidential and Proprietary


Subscriptions

YouTube Confidential and Proprietary


Subscriptions
/feeds/api/users/<username>/subscriptions

There are multiple types of subscriptions:


Channel
Favorites
Search query

Differentiate by category
<category scheme='http://…/schemas/2007/subscriptiontypes.cat‘
term='channel'/>

Identify target by entry contents


<yt:username> for Channel, Favorites
<yt:queryString> for Search YouTube Confidential and Proprietary
Subscriptions (Atom)
<entry>
<id>http://…/users/mortms/subscriptions/ac3a969d054c3f98</id>
<category scheme='http://…/schemas/2007/subscriptiontypes.cat‘
term='channel'/>
<yt:username>lonelygirl15</yt:username>
<gd:feedLink rel='http://…/schemas/2007#user.uploads‘
href='http://…/feeds/api/users/lonelygirl15/uploads‘
countHint='309'/>
</entry>
<entry>
<id>http://…/users/mortms/subscriptions/83bd95e382641fc2</id>
<category scheme='http://…/schemas/2007/subscriptiontypes.cat‘
term='query'/>
<yt:queryString>virginia tech</yt:queryString>
<gd:feedLink rel='http://…/schemas/2007#video.query‘
href='http://…/feeds/api/videos?vq=virginia+tech'/>
</entry>

YouTube Confidential and Proprietary


Playlists

YouTube Confidential and Proprietary


Playlists

/feeds/api/users/<username>/playlists

Each playlist has:


Title
Description
Tags
<gd:feedLink> pointing to playlist contents
<entry>
<category scheme='http://.../tags.cat' term='snowboard'/>
<title type='text'>April 26 2008 at Squaw Valley</title>
<content type='text'>A few videos from snowboarding at Squaw
Valley on April 26, 2008</content>
<gd:feedLink rel='http://…/schemas/2007#playlist'
href='http://…/feeds/api/playlists/190CCAA9B6D4481B'
countHint='4'/>
</entry>
YouTube Confidential and Proprietary
Playlist Contents
/feeds/api/playlists/<playlist-id>

Almost identical to search results, standard feeds, etc.

Playlist contents have <yt:position>

<entry>
<title type='text'>Android Demo</title> ...
<yt:position>1</yt:position>
</entry>
<entry>
<title type='text'>A first hand look at building an Android
application</title> …
<yt:position>2</yt:position>
</entry>

YouTube Confidential and Proprietary


Favorites and User Uploads

YouTube Confidential and Proprietary


Favorites and User Uploads
/feeds/api/users/<username>/favorites

Simple collection of videos marked as “Favorite” by user.

/feeds/api/users/<username>/uploads

Set of videos uploaded by the user


If not logged in – returns live, public videos only
If logged in – returns all user’s uploads

YouTube Confidential and Proprietary


Example Time – Favorites and User Uploads

YouTube Confidential and Proprietary


Example Time – Favorites and User Uploads

feed = yt.GetUserFavoritesFeed(
username=‘danielbeast')

uri = '/feeds/api/users/default/uploads'
feed = yt.GetYouTubeVideoFeed(uri)

YouTube Confidential and Proprietary


A note about projections

Projections allow you to get just the data you’re interested in

/feeds/api/…
All relevant data, using plain text instead of HTML

/feeds/base/…
Simple responses with HTML for display

/feeds/mobile/…
Most compact responses for low-bandwidth mobile devices.

YouTube Confidential and Proprietary


Why should users log in?

Access to restricted information


Private videos
Private playlists
Inbox (video sharing)
Status of videos being processed

Required for all write operations


Modify favorites, playlists, subscriptions
Rate, comment, respond to videos
Upload and manage videos

YouTube Confidential and Proprietary


Login

Two ways to sign in

Web applications use AuthSub


Users log in on a Google web page
Browser gets redirected back to your site with authentication token

Installed applications use ClientLogin


Users enter credentials in your application
Your application makes a login request
Your application gets issued a temporary authentication token

YouTube Confidential and Proprietary


AuthSub Overview

Send user to AuthSub login page

https://www.google.com/accounts/AuthSubRequest?
next=http://your.app.com/login_complete
scope=http://gdata.youtube.com
session=1&secure=0

YouTube Confidential and Proprietary


AuthSub Overview

User will be sent back to your site with a one-time use token
http://your.app.com/login_complete?token=<one-time-token>

Use or convert to session token


https://www.google.com/accounts/AuthSubSessionToken

Add Authorization header to all requests:


Authorization: AuthSub token=“<one-time-token>”

YouTube Confidential and Proprietary


Basic write operations

Can create, update, and delete data

All write operations require a user auth token

We also require you to register your application


http://code.google.com/apis/youtube/dashboard/
Use one developer key for each application/product

Send auth token, developer key, client id with every request


Authorization: AuthSub token=“<token>”
X-GData-Key: key=<developer-key>
X-GData-Client: <client-id>

YouTube Confidential and Proprietary


Basic write operations

Make POST requests to create a new entry:


Favorite
Playlist or playlist item
Subscription
Comments & Responses
Contacts

Some feeds are write-only


Ratings
Complaints

YouTube Confidential and Proprietary


Write example
POST /feeds/api/users/default/favorites HTTP/1.1
X-GData-Key: key=<developer-key>
X-GData-Client: key=<client-id>
Authorization: AuthSub token=“<token>”
Content-Type: application/atom+xml

<?xml version='1.0' encoding='UTF-8'?>


<entry xmlns='http://www.w3.org/2005/Atom'>
<id>http://gdata.youtube.com/feeds/videos/u1zgFlCw8Aw</id>
</entry>

YouTube Confidential and Proprietary


Upload

Two models for upload

Direct Upload
For installed applications
For web apps, if you have (or want) a copy of the video

Browser Upload
For web apps only
Your app controls the metadata
User uploads the video directly to YouTube

YouTube Confidential and Proprietary


Upload

Developer tags allow you to track your uploads

Accessible only with your developer key

Can define your own taxonomy

<entry>
...
<media:group>
<media:category scheme='…/schemas/2007/developertags.cat'>
my_user_id=john
</media:category>
<media:category scheme=‘…/schemas/2007/developertags.cat'>
type=test
</media:category>
</media:group>
</entry>

YouTube Confidential and Proprietary


Direct Upload Example

All uploads go to http://uploads.gdata.youtube.com


POST /feeds/api/users/default/uploads HTTP/1.1
X-GData-Key: key=<developer-key>
X-GData-Client: key=<client-id>
Authorization: AuthSub token=“<token>”
Content-Type: multipart/related; boundary=Arbitrary-String
Slug: original_file.mp4

--Arbitrary-String

Content-Type: application/atom+xml

<entry>…</entry>
--Arbitrary-String

Content-Type: video/mp4
Content-Transfer-Encoding: binary

[Binary data of file]


--Arbitrary-String--

YouTube Confidential and Proprietary


Browser Upload Flow

YouTube Confidential and Proprietary


Browser Upload Flow

YouTube Confidential and Proprietary


Browser Upload Flow

YouTube Confidential and Proprietary


Browser Upload Flow

YouTube Confidential and Proprietary


Example Time – Browser Upload

YouTube Confidential and Proprietary


Browser Upload Example
Step 3: POST Metadata, including developer tags
POST /actions/GetUploadToken HTTP/1.1
X-GData-Key: key=<developer-key>
X-GData-Client: key=<client-id>
Authorization: AuthSub token=“<token>”
Content-Type: application/atom+xml; charset=UTF-8

<entry> …
<media:category scheme=http://.../schemas/2007/developertags.cat>
my_user_id=john </media:category>
… </entry>
Step 4: Receive upload URL and token
<?xml version='1.0' encoding='UTF-8'?>
<response>
<url>http://uploads.gdata.youtube.com/action/FormDataUpload/AIw…<url>
<token>AIwbFAS…b9gtLCYjoE-</token>
</response>
YouTube Confidential and Proprietary
Browser Upload Example
Step 5: Display upload form
<form action="http://uploads.gdata.../FormDataUpload/AIw...?
nexturl=http://mysite.com/upload_complete“
method="post“ enctype="multipart/form-data">
Video File: <input type="file" name="file"/>
<input type="hidden" name="token" value="AIw…YjoE-"/>
<input type="submit"/>
</form>

Step 8: User gets redirected to your site on completion


http://mysite.com/upload_complete?status=200&id=GTdQIBGlEmg

YouTube Confidential and Proprietary


Checking Video Status

Not public, so will not show up in public feeds


Retrieve from authenticated user uploads feed:
GET /feeds/api/users/default/uploads/GTdQIBGlEmg HTTP/1.1
X-GData-Key: key=<developer-key>
X-GData-Client: key=<client-id>
Authorization: AuthSub token=“<token>”
Check for status tags (not present means video is live):
<app:control xmlns:app='http://purl.org/atom/app#'>
<app:draft>yes</app:draft>
<yt:state name='processing'/>
</app:control>

Also check when showing all of user’s uploads

YouTube Confidential and Proprietary


Searching with developer tags

Developer tags are simply a category scheme

Search with standard category syntax


{category_scheme}category_name
GET /feeds/api/videos/-/
{…/schemas/2007/developertags.cat}my_user_id=john HTTP/1.1
X-GData-Key: key=<developer-key>
X-GData-Client: key=<client-id>

YouTube Confidential and Proprietary


Example Time – Developer Tags

YouTube Confidential and Proprietary


References

Google Data API documentation


http://code.google.com/apis/gdata/overview.html

YouTube Data API documentation


http://code.google.com/apis/youtube/overview.html

YouTube API Developer Forum


http://groups.google.com/group/youtube-api?lnk=srg

YouTube Confidential and Proprietary


Q&A
Appendix
Video Feeds
Sample video feed
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' …>
<id>http://gdata.youtube.com/…/standardfeeds/most_viewed</id> …
<link rel='next' type='application/atom+xml'
href=‘…viewed?start-index=26&max-results=25&time=all_time'/>
<openSearch:totalResults>100</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry>
<id>http://…/feeds/api/videos/dMH0bHeiRNg</id> …
<title type='text'>Evolution of Dance</title> …
<author><name>judsonlaipply</name>…</author> …
<media:group> … </media:group> …
</entry>
<entry>
<id>http://…/feeds/api/videos/cQ25-glGRzI</id> …
<title type='text'>Avril Lavigne - Girlfriend</title>

</feed>

YouTube Confidential and Proprietary


Video Feeds
Sample video entry
<entry>
<id>http://…/feeds/api/videos/dMH0bHeiRNg</id> …
<category scheme=‘…/keywords.cat' term='Dancing'/> …
<category scheme=‘…/categories.cat' term='Comedy‘
label='Comedy'/>
<title type='text'>Evolution of Dance</title>
<content type='text'>The funniest 6 minutes…</content>
<link rel='alternate' type='text/html‘
href='http://www.youtube.com/watch?v=dMH0bHeiRNg'/>
<link rel='http://…/schemas/2007#video.responses‘
type='application/atom+xml‘
href='http://…/videos/dMH0bHeiRNg/responses'/>
<link rel='http://…/schemas/2007#video.related‘
type='application/atom+xml‘
href='http://…/videos/dMH0bHeiRNg/related'/>
<media:group> …

YouTube Confidential and Proprietary


Video Feeds
Sample video entry (cont’d)

<media:group> ...
<yt:duration seconds='360'/>
<media:content url='http://www.youtube.com/v/dMH0bHeiRNg‘
type='application/x-shockwave-flash' medium='video‘
isDefault='true‘ expression='full' duration='360‘
yt:format='5'/> …
<media:player url='http://youtube.com/watch?v=dMH0bHeiRNg'/>
<media:thumbnail
url='http://img.youtube.com/vi/dMH0bHeiRNg/2.jpg‘
height='97' width='130' time='00:03:00'/> …
</media:group>
<yt:statistics viewCount='84153989' favoriteCount='443906'/>
<gd:rating min='1' max='5' numRaters='312593' average='4.65'/>
<gd:comments>
<gd:feedLink href='http://…/videos/dMH0bHeiRNg/comments‘
countHint='151497'/>
</gd:comments>
</entry>

YouTube Confidential and Proprietary

You might also like